home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / arcers / tar316.zip / DISK.C < prev    next >
Text File  |  1980-07-24  |  9KB  |  315 lines

  1. /* disk.c - MS-DOS diskette service for Tar program (see file tar.c)
  2.  * Author: T.V.Shaporev
  3.  * Prepared for release 19 Oct 1990
  4.  *
  5.  * Called by readtape(), writetape() etc. - see file tape.c
  6.  */
  7. #include "sysup.h"
  8. #ifdef __TURBOC__
  9.  
  10. #include <string.h>
  11. #include <stdio.h>
  12.  
  13. #include "modern.h"
  14. #include "define.h"
  15.  
  16. extern int  diskserv __ARGS__((int, int, int, int, int, int, void far *));
  17. extern void printbs  __ARGS__(( int ));
  18.  
  19. static void errdisk  __ARGS__(( int ));
  20. static void redrive  __ARGS__(( void ));
  21. static int  trydisk  __ARGS__(( int, char *, int ));
  22. static void nextdisk __ARGS__(( void ));
  23. static void skipsect __ARGS__(( void ));
  24. static void ibmdisk  __ARGS__(( int, char *, int ));
  25. static void rainbow  __ARGS__(( int, char *, int ));
  26.  
  27. #define FDC_STATUS  (*(char far *)0x0490L)
  28.  
  29. static unsigned short heads, tracks, sectors, last_seg, this_seg;
  30. static char calibr = 0;
  31.  
  32. struct   { char *type_disk; unsigned size, heads, tracks, sectors; }
  33.        ftab[] = { {"fd048ss8",       160,  1,     40,       8  },
  34.                   {"fd048ss9",       180,  1,     40,       9  },
  35.                   {"fd048ds8",       320,  2,     40,       8  },
  36.                   {"fd048ds9",       360,  2,     40,       9  },
  37.                   {"fd135ds9",       720,  2,     80,       9  },
  38.                   {"fd096ds9",       720,  2,     80,       9  },
  39.                   {"fd096ds15",     1200,  2,     80,      15  },
  40.                   {"fd135ds18",     1440,  2,     80,      18  } };
  41.  
  42. static void errdisk(n)
  43. int n;
  44. {
  45.    register int i;
  46.    static struct { unsigned char code; char *text; } errtab[] = {
  47.    {    0, "undefined error" },
  48.    { 0x00, "no error on last operation" },
  49.    { 0x01, "invalid request to controller" },
  50.    { 0x02, "bad address mark" },
  51.    { 0x03, "write protect" },
  52.    { 0x04, "sector ID bad or not found" },
  53.    { 0x05, "reset failed" },
  54.    { 0x06, "floppy changed line on" },
  55.    { 0x08, "DMA failure" },
  56.    { 0x09, "DMA overrun: attempted to write across 64K" },
  57.    { 0x0b, "bad track flag encountered" },
  58.    { 0x0C, "media type not found" },
  59.    { 0x10, "bad CRC: invalid CRC when data checked" },
  60.    { 0x11, "recoverable error found; data corrected" },
  61.    { 0x20, "controller failure" },
  62.    { 0x40, "bad seek; requested track not found" },
  63.    { 0x80, "time out; drive did not respond" },
  64.    { 0xff, "sense operation failed" } };
  65.  
  66.    for (i=1; errtab[i].code!=n && i<dimof(errtab); i++) ;
  67.    if (i>=dimof(errtab)) i = 0;
  68.    fprintf(myout, "Tar: diskette error: %s\n", errtab[i].text);
  69. }
  70.  
  71. int argdisk(k)
  72. register k;
  73. {
  74.    register i;
  75.  
  76.    for (i=0; ftab[i].size!=k && i<dimof(ftab); i++) ;
  77.    if (i >= dimof(ftab)) return -1;
  78.    sectors  = ftab[i].sectors;
  79.    tracks   = ftab[i].tracks;
  80.    heads    = ftab[i].heads;
  81.    return 0;
  82. }
  83.  
  84. int defdev(k)
  85. register char *k;
  86. {
  87.    register i;
  88.  
  89.    for (i=0; stricmp(ftab[i].type_disk, k)!=0 && i<dimof(ftab); i++) ;
  90.    if (i < dimof(ftab)) {
  91.       sectors = ftab[i].sectors;
  92.       tracks  = ftab[i].tracks;
  93.       heads   = ftab[i].heads;
  94.    } else if (stricmp("rainbow", k) == 0) {
  95.       calibr  = RAINBOW;
  96.       sectors = 10;
  97.       tracks  = 80;
  98.       heads   = 1;
  99.    } else {
  100.       return -1;
  101.    }
  102.    return 0;
  103. }
  104.  
  105. static void redrive() /* reset & recalibrate drive */
  106. {
  107.    (void)diskserv(0, ndrive, 0, 0, 1, 1, NULL);
  108.    if (calibr & QUADISK) {/* Init 800 */
  109.       FDC_STATUS = 0x61;      /* FDC status buts <- 61h - ??? */
  110.       /* verify Track 0 Sector 1 Side 0 */
  111.       (void)diskserv(4, ndrive, 0, 0, 1, 1, NULL);
  112.       /* verify Track 1 Sector 1 Side 0 */
  113.       (void)diskserv(4, ndrive, 0, 1, 1, 1, NULL);
  114.       (void)diskserv(0, ndrive, 0, 0, 1, 1, NULL);
  115.       FDC_STATUS = 0x54;      /* FDC status buts <- 54h - ??? */
  116.    } else if (calibr != 0) {
  117.       (void)diskserv(0x17, ndrive, 0, 0, 1, calibr, NULL);
  118.    }
  119. }
  120.  
  121. void inidisk(void)
  122. {
  123.    register k;
  124.    unsigned tb;
  125.    struct {
  126.       short int ndisks, maxhead, maxtrack, maxsect;
  127.    } dp;
  128.  
  129.    if (!calibr) {
  130.       /* reset drive */
  131.       (void)diskserv(0, ndrive, 0, 0, 1, 1, NULL);
  132.       /* get drive params (set default to 2x40x9) */
  133.       (void)diskserv(8, ndrive, 1, 39, 9, 9, &dp);
  134.  
  135.       if ((tb = ++(dp.maxhead) * ++(dp.maxtrack) * dp.maxsect) == 0) {
  136.          fprintf(stderr, "Tar: drive not present\n");
  137.          done(ERINIT);
  138.       }
  139.       if (!k_flag) {
  140.          sectors = dp.maxsect; tracks = dp.maxtrack; heads = dp.maxhead;
  141.          if (v_flag) fprintf(myout, "Diskette capacity %uK assigned\n",
  142.                             tb / (1024/BLKSIZE) );
  143.       }
  144.       last_seg = sectors*tracks*heads;
  145.       if        (last_seg == 2880) {
  146.          calibr = tb == 2880 ? 3 : 0;
  147.       } else if (last_seg == 2400) {
  148.          calibr = tb == 2400 ? 3 : 0;
  149.       } else if (last_seg == 1440) {
  150.          calibr = tb == 2880 ? 2 :
  151.                   tb == 2400 ? QUADISK :
  152.                   tb == 1440 ? 4 : 0;
  153.       } else if (last_seg == 720) {
  154.          calibr = tb == 2400 ? 2 : tb == 720 ? 1 : 0;
  155.       } else if (last_seg == 640) {
  156.          calibr = tb == 2400 ? 2 : tb == 720 || tb == 640 ? 1 : 0;
  157.       } else if (last_seg == 360) {
  158.          calibr = tb == 2400 ? 2 : tb == 720 || tb == 360 ? 1 : 0;
  159.       } else if (last_seg == 320) {
  160.          calibr = tb == 2400 ? 2 : tb == 720 || tb == 360 ||
  161.                                    tb == 640 || tb == 320 ? 1 : 0;
  162.       }
  163.    }
  164.    this_seg = 0;
  165.  
  166.    redrive();
  167.  
  168.    /* get drive error status */
  169.    k = diskserv(1, ndrive, 0, 0, 1, 1, NULL);
  170.    if (k!=0 && k!=6) {
  171.       errdisk(k);
  172.       if (k!=0x11) done(ERINIT);
  173.    }
  174.    if (!cblock) {
  175.       /* Some BIOSes do strange things on quad drives.              */
  176.       /* I guess they loose info while read or write through 9th to */
  177.       /* 10th sector.  I hope, the following solves the problem.    */
  178.       printbs(cblock = a_flag ? 1 : (sectors < 9 ? sectors : 3));
  179.    }
  180. }
  181.  
  182. static int trydisk(wr, buf, bl)
  183. int wr, bl;
  184. char *buf;
  185. {
  186.    int i, k;
  187.    register short s, h, t;
  188.  
  189.    s  = this_seg % sectors + 1; /* sector */
  190.    t  = this_seg / sectors;
  191.    h  = t % heads;              /* head   */
  192.    t /= heads;                  /* track  */
  193.  
  194.    i = 0;
  195.    do {
  196.       k = diskserv((wr ? 3 : 2), ndrive, h, t, s, bl, buf);
  197. #if 0
  198.       if (!k && wr) {/* verify */
  199.          char chk[NBLOCK*BLKSIZE];
  200.          k = diskserv(4, ndrive, h, t, s, bl, buf);
  201.       }
  202. #endif
  203.       if (k) redrive();
  204.    } while (k && ++i<3);
  205.  
  206.    if (cbreak) done(0);
  207.  
  208.    if (k == 0 || k == 0x11) {
  209.       k = 0;
  210.    } else if (k!=0x02 && k!=0x04 && k!=0x0B && k!=0x10 && k!=0x40) {
  211.       errdisk(k); /* fatal error */
  212.       if (!i_flag || wr) done(wr ? EWRITE : ERREAD);
  213.    }
  214.    return k;
  215. }
  216.  
  217. static void nextdisk()
  218. {
  219.    fprintf(stderr, "Tar: insert NEXT diskette and press ENTER when ready...");
  220.    (void)yes_no('\0');
  221.    this_seg = 0;
  222.    redrive();
  223. }
  224.  
  225. static void skipsect()
  226. {
  227.    fprintf(myout, "Tar: warning: bad sector %d, skipped\n", this_seg);
  228. }
  229.  
  230. static void ibmdisk(wr, buf, bl)
  231. int wr, bl;
  232. char *buf;
  233. {
  234.    int i, j, k;
  235.  
  236.    i = sectors - this_seg % sectors;
  237.    if (i > bl) i = bl;
  238.    while (bl > 0) {
  239.       if (this_seg >= last_seg) nextdisk();
  240.       if ((k = trydisk(wr, buf, i)) == 0) {
  241.          this_seg += i;
  242.          buf      += i*BLKSIZE;
  243.          bl       -= i;
  244.       } else {
  245.          for (j=0; j<i; j++)  {
  246.             if (i>1) k = trydisk(wr, buf, 1);
  247.             if (k == 0) { /* one sector o'k */
  248.                buf += BLKSIZE;
  249.                --bl;
  250.             } else skipsect();
  251.             ++this_seg;
  252.          }
  253.       }
  254.       i = sectors < bl ? sectors : bl;
  255.    }
  256. }
  257.  
  258. static void rainbow(wr, buf, bl)
  259. int wr, bl;
  260. char *buf;
  261. {
  262.    int i, j, k, n;
  263.    static char e85tab[50] = {
  264.    /*  x  =   0   1   2   3   4   5   6   7   8   9  */
  265.    /* 0x */   1,  3,  5,  7,  9,  2,  4,  6,  8, 10,
  266.    /* 1x */   3,  5,  7,  9,  1,  4,  6,  8, 10,  2,
  267.    /* 2x */   5,  7,  9,  1,  3,  6,  8, 10,  2,  4,
  268.    /* 3x */   7,  9,  1,  3,  5,  8, 10,  2,  4,  6,
  269.    /* 4x */   9,  1,  3,  5,  7, 10,  2,  4,  6,  8,
  270.    };
  271.  
  272.    while (bl > 0) {
  273.       if (this_seg >= last_seg) nextdisk();
  274.  
  275.       i = (this_seg/10 + 1) % 80; /* track  */
  276.       j = e85tab[this_seg%50];    /* sector */
  277.       n = 0;
  278.       do {
  279.          k = diskserv((wr?3:2), ndrive, 0, i, j, 1, buf);
  280.          if (k && ++n<3) redrive();
  281.       } while (k && n<3);
  282.  
  283.       if (cbreak) done(0); /* ??? */
  284.  
  285.       if (!k) { buf += BLKSIZE; --bl; } else skipsect();
  286.       ++this_seg;
  287.    }
  288. }
  289.  
  290. /* Interface routines */
  291. int dread(buf, n)
  292. char *buf; register n;
  293. {
  294.    register k = n / BLKSIZE;
  295.    if (n % BLKSIZE) return -1;
  296.    if (calibr == RAINBOW) rainbow(0, buf, k); else ibmdisk(0, buf, k);
  297.    return n;
  298. }
  299.  
  300. int dwrite(buf, n)
  301. char *buf; register n;
  302. {
  303.    n = (BLKSIZE-1 + n) / BLKSIZE;
  304.    if (calibr == RAINBOW) rainbow(1, buf, n); else ibmdisk(1, buf, n);
  305.    return BLKSIZE*n;
  306. }
  307.  
  308. int dback(n)
  309. register n;
  310. {
  311.    this_seg = this_seg > n ? this_seg-n : 0;
  312.    return n;
  313. }
  314. #endif
  315.